#include "blockqueue.hpp"
#include "task.hpp"

#include <unistd.h>
#include <ctime>

//消费行为
void* Consumer(void* args)
{
    BlockQueue<Task>* bq = static_cast<BlockQueue<Task>*>(args);

    while(true)
    {
        //1.拿任务
        Task t = bq->pop();

        //2.处理任务
        t();
        std::cout << "处理任务: " << t.GetTask() 
        << " 运算结果是： " << t.GetResult() 
        << " thread id: " << pthread_self() << std::endl;
    }
}

//生产行为
void* Productor(void* args)
{
    BlockQueue<Task>* bq = static_cast<BlockQueue<Task>*>(args);

    int len = opers.size();
    while (true)
    {
        //获取任务
        int data1 = rand() % 10 + 1; // [1,10]
        usleep(10);
        int data2 = rand() % 10;
        char op = opers[rand() % len];
        Task t(data1, data2, op);

        //放任务
        bq->push(t);
        std::cout << "生产了一个任务: " << t.GetTask() 
        << " thread id: " << pthread_self() << std::endl;
        sleep(1);
    }
}

int main()
{
    //随机数种子
    srand(time(nullptr));

    //创建任务队列
    BlockQueue<Task>* bq = new BlockQueue<Task>();

    //单生产单消费
    // pthread_t c, p;
    // pthread_create(&c, nullptr, Consumer, (void*)bq);
    // pthread_create(&p, nullptr, Productor, (void*)bq);

    // pthread_join(c, nullptr);
    // pthread_join(p, nullptr);
    
    //多生产多消费
    pthread_t c[3], p[5];
    for (int i = 0; i < 3; i++)
    {
        pthread_create(c + i, nullptr, Consumer, bq);
    }
    for (int i = 0; i < 5; i++)
    {
        pthread_create(p + i, nullptr, Productor, bq);
    }

    for (int i = 0; i < 3; i++)
    {
        pthread_join(c[i], nullptr);
    }
    for (int i = 0; i < 5; i++)
    {
        pthread_join(p[i], nullptr);
    }

    delete bq;
    return 0;
}